package com.easepal.softaplib;

import android.os.Handler;

import java.io.InputStream;
import java.io.OutputStream;

/**
 * 作者: bright.lin@medisana.net.cn
 * 时间: 2018/12/19
 * 标题: BIO的Socket连接管理
 * 描述: 用于管理Socket连接
 * 修改: 由 bright.lin@medisana.net.cn 修改于 2018/12/19
 */
class BioConnector {
    // 连接状态-连接关闭
    private final int STATE_CLOSE = 0x1;
    // 连接状态-连接开始
    private final int STATE_CONNECT_START = 0x2;
    // 连接状态-连接成功
    private final int STATE_CONNECT_SUCCESS = 0x3;

    // 连接超时时长
    private long connectTimeout = 10000;
    // TCP连接的ip地址
    private String tcpIp = null;
    // TCP连接的端口
    private int port = 0;
    // 连接状态-初始化为连接关闭
    private int state = STATE_CLOSE;

    // Socket客户端
    private BioClient mClient;
    // 连接监听回调
    private IConnectListener mIConnectListener;
    // Socket读写处理
    private BioReadWriteProcessor mSocketProcessor;

    // 内部连接监听回调
    private BioConnectListener mProxyConnectStatusListener = new BioConnectListener() {
        @Override
        public synchronized void onConnectSuccess(BioReadWriteProcessor mSocketProcessor, OutputStream mOutputStream, InputStream mInputStream) {
            if (mSocketProcessor != BioConnector.this.mSocketProcessor) {//两个请求都不是同一个，说明是之前连接了，现在重连了
                BioReadWriteProcessor dropProcessor;
                dropProcessor = mSocketProcessor;
                if (null != dropProcessor) {
                    dropProcessor.close();
                }
                return;
            }

            state = STATE_CONNECT_SUCCESS;
            mClient.init(mOutputStream, mInputStream);

            if (null != mIConnectListener) {
                mIConnectListener.onConnectionSuccess();
            }
        }

        @Override
        public synchronized void onConnectFailed(BioReadWriteProcessor mSocketProcessor) {
            if (mSocketProcessor != BioConnector.this.mSocketProcessor) {//两个请求都不是同一个，说明是之前连接了，现在重连了
                BioReadWriteProcessor dropProcessor;
                dropProcessor = mSocketProcessor;
                if (null != dropProcessor) {
                    dropProcessor.close();
                }
                return;
            }

            state = STATE_CLOSE;
            if (null != mIConnectListener) {
                mIConnectListener.onConnectionFailed();
            }
        }
    };

    /**
     * 带参构造器
     *
     * @param mClient           Socket客户端
     * @param mIConnectListener 连接监听回调
     */
    BioConnector(BioClient mClient, IConnectListener mIConnectListener) {
        this.mClient = mClient;
        this.mIConnectListener = mIConnectListener;
    }

    /**
     * 获取已连接状态
     *
     * @return 已连接状态
     */
    boolean isConnected() {
        return state == STATE_CONNECT_SUCCESS;
    }

    /**
     * 获取连接中状态
     *
     * @return 连接中状态
     */
    private boolean isConnecting() {
        return state == STATE_CONNECT_START;
    }

    /**
     * 获取已关闭状态
     *
     * @return 已关闭状态
     */
    private boolean isClosed() {
        return state == STATE_CLOSE;
    }

    /**
     * 设置连接地址
     *
     * @param tcpIp ip地址
     * @param port  端口
     */
    void setConnectAddress(String tcpIp, int port) {
        this.tcpIp = tcpIp;
        this.port = port;
    }

    /**
     * 设置超时时长
     *
     * @param connectTimeout 超时时长
     */
    void setConnectTimeout(long connectTimeout) {
        this.connectTimeout = connectTimeout;
    }

    /**
     * 连接
     */
    synchronized void connect() {
        startConnect();
    }

    /**
     * 重连
     */
    synchronized void reconnect() {
        stopConnect();
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                startConnect();
            }
        },2000);

    }

    /**
     * 断开连接
     */
    synchronized void disconnect() {
        stopConnect();
    }

    /**
     * 检查连接状态（已连接时唤醒写线程）
     */
    void checkConnect() {
        //1.没有连接,需要进行重连
        //2.在连接不成功，并且也不在重连中时，需要进行重连;
        if (null == mSocketProcessor) {
            startConnect();
        } else if (!isConnected() && !isConnecting()) {
            startConnect();
        } else {
            if (isConnected()) {
                mSocketProcessor.wakeUp();
            }/* else {
                //说明正在重连中
            }*/
        }
    }

    /**
     * 开始连接
     */
    private void startConnect() {
        //非关闭状态(连接成功，或者正在重连中)
        if (!isClosed()) {
            return;
        }

        state = STATE_CONNECT_START;
        mSocketProcessor = new BioReadWriteProcessor(tcpIp, port, connectTimeout, mClient, mProxyConnectStatusListener);
        mSocketProcessor.start();
    }

    /**
     * 停止连接
     */
    private void stopConnect() {
        state = STATE_CLOSE;
        mClient.onClose();

        if (null != mSocketProcessor) {
            mSocketProcessor.close();
            mSocketProcessor = null;
        }
    }
}
